package com.ljj.admin.mybatis.system.services.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.ljj.admin.mybatis.system.beans.SysMenu;
import com.ljj.admin.mybatis.system.beans.SysRoleMenuKey;
import com.ljj.admin.mybatis.system.beans.SysUser;
import com.ljj.admin.mybatis.system.mapper.SysMenuDAO;
import com.ljj.admin.mybatis.system.mapper.SysRoleMenuDAO;
import com.ljj.admin.mybatis.system.services.ISysMenusService;
import com.ljj.admin.web.bean.common.CheckArr;
import com.ljj.admin.web.bean.common.DTree;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;

/**
 * 菜单 业务层
 */
@Service
public class SysMenusService implements ISysMenusService {

    @Autowired
    private SysMenuDAO sysMenuDAO;


    @Autowired
    private SysRoleMenuDAO sysRoleMenuDAO;

    public List<SysMenu> getMenusAll(SysUser sysUser) {
        return sysMenuDAO.selectMenuAll();
    }


    public List<SysRoleMenuKey> selectByMenuId(long menuId){
        return sysRoleMenuDAO.selectByMenuId(menuId);
    }

    /**
     * 根据 parentId  获取 菜单信息
     * @param menuId
     * @return
     */
    public List<SysMenu> selectByParentId(long menuId){
        return sysMenuDAO.selectByParentId(menuId);
    }

    @Override
    public List<SysMenu> selectMenuPermsByUserId(Long userId) {
        return null;
    }


    /**
     * 根据Id 获取 menu 信息
     *
     * @param menuId
     * @return
     */
    public SysMenu selectByPrimaryKey(long menuId) {
        return sysMenuDAO.selectByPrimaryKey(menuId);
    }


    public Set<String> selectPermsByUserId(long userId)
    {
        List<SysMenu> sysMenus = sysMenuDAO.selectMenuPermsByUserId(userId);
        Set<String> collect = sysMenus.stream().filter(p -> !StringUtils.isEmpty(p.getPerms())).map(p -> {
            return p.getPerms();
        }).collect(Collectors.toSet());

        return collect;
    }


    @Override
    public int deleteByPrimaryKey(Long menuId) {
        return 0;
    }

    @Override
    public int insert(SysMenu record) {
        return 0;
    }

    /**
     * 新增 菜单信息
     * @param sysMenu
     * @return
     */
    public int insertSelective(SysMenu sysMenu) {

        return sysMenuDAO.insertSelective(sysMenu);
    }

    @Override
    public SysMenu selectByPrimaryKey(Long menuId) {
        return null;
    }


    /**
     * 更新
     * @param sysMenu
     * @return
     */
    public int updateByPrimaryKeySelective(SysMenu sysMenu)
    {
        return sysMenuDAO.updateByPrimaryKeySelective(sysMenu);
    }

    @Override
    public int updateByPrimaryKeyWithBLOBs(SysMenu record) {
        return 0;
    }

    @Override
    public int updateByPrimaryKey(SysMenu record) {
        return 0;
    }

    @Override
    public List<SysMenu> selectMenuAll() {
        return null;
    }

    @Override
    public List<SysMenu> selectMenuList() {
        return null;
    }


    public int deleteByPrimaryKey(long menuId)
    {
        return sysMenuDAO.deleteByPrimaryKey(menuId);
    }


    /**
     * 根据父节点的ID获取所有子节点
     *
     * @param list     分类表
     * @param parentId 传入的父节点ID
     * @return String
     */
    private List<SysMenu> getChildPerms(List<SysMenu> list, int parentId) {
        List<SysMenu> returnList = new ArrayList<>();
        list.stream().filter(t -> t.getParentId() == parentId).forEach(t -> {
            recursionFn(list, t);
            returnList.add(t);
        });

        return returnList;
    }

    /**
     * 递归列表
     *
     * @param list 菜单列表
     */
    private void recursionFn(List<SysMenu> list, SysMenu t) {
        // 得到子节点列表
        List<SysMenu> childList = getChildList(list, t);
        t.setChildern(childList);
        for (SysMenu tChild : childList) {
            if (hasChild(list, tChild)) {
                // 判断是否有子节点
                for (SysMenu n : childList) {
                    recursionFn(list, n);
                }
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<SysMenu> getChildList(List<SysMenu> list, SysMenu t) {
        List<SysMenu> tlist = new ArrayList<>();
        list.stream().filter(sysMenu -> sysMenu.getParentId().equals(t.getMenuId())).forEach(tlist::add);
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<SysMenu> list, SysMenu t) {
        return !CollectionUtils.isEmpty(getChildList(list, t));
    }


    /**
     * 根据用户信息获取全部 菜单信息  用于 前端显示
     *
     * @param sysUser
     * @return
     */
    public List<SysMenu> GetSysMenuListByUser(SysUser sysUser) {
        Long userId=null;

        if(ObjectUtil.isNotNull(sysUser))
        {
            if(!"admin".equalsIgnoreCase(sysUser.getLoginName()))
            {
                userId=sysUser.getUserId();
            }
        }
        List<SysMenu> menus = sysMenuDAO.selectMenuPermsByUserId(userId);
        return getChildPerms(menus, 0);
    }


    /**
     * 根据 角色ID 获取 菜单树
     *
     * @param roleId
     * @return
     */
    public List<DTree> GetSysMenuDTreeByUser(long roleId) {
        List<SysMenu> sysMenus = sysMenuDAO.selectMenuList();

        List<SysRoleMenuKey> sysRoleMenuKeys = sysRoleMenuDAO.selectMenuIdByRoleId(roleId);

        List<DTree> dTrees = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(sysMenus)) {
            for (SysMenu sysMenu : sysMenus) {
                DTree dTree = new DTree();
                CheckArr checkArr = new CheckArr();
                long menuCount = sysRoleMenuKeys.stream().filter(p -> p.getMenuId().intValue() == sysMenu.getMenuId().intValue() && p.getRoleId().intValue() == (int) roleId).toArray().length;
                if (menuCount > 0) {
                    checkArr.setChecked("1");
                }
                dTree.setCheckArr(checkArr);
                dTree.setId(sysMenu.getMenuId().toString());
                dTree.setTitle(sysMenu.getMenuName() + sysMenu.getPerms());
                dTree.setParentId(sysMenu.getParentId().toString());
                dTree.setLast(false);
                dTree.setSpread(false);
                dTrees.add(dTree);
            }


        }

        return dTrees;
    }


}
